package abordagem.leitores_e_escritores;

import java.util.concurrent.Semaphore;

import main.Principal;

/**
 * Banco da abordagem RW. Para mais informacoes sobre a abordagem RW: {@link Principal}
 * 
 * @author Andreia Rodrigues de Oliveira, Raphael Henrique Monteiro, Regis Hideki Hatori;
 * 
 */
public class RWDatabase implements RWLock {

	private int readerCount;
	private Semaphore mutex;
	private Semaphore db;

	/**
	 * Construtor da classe RWDatabase
	 */
	public RWDatabase() {
		
		readerCount = 0;
		mutex = new Semaphore(1);
		db = new Semaphore(1);
	}

	@Override
	/**
	 * @see abordagem.leitores_e_escritores.RWLock
	 */
	public void acquireReadLock() {

		try {

			mutex.acquire();
			++readerCount;

			if (readerCount == 1) {
				db.acquire();
			}

			mutex.release();

		} catch (InterruptedException e) {

			e.printStackTrace();
		}
	}

	@Override
	/**
	 * @see abordagem.leitores_e_escritores.RWLock
	 */
	public void acquireWriteLock() {

		try {

			db.acquire();

		} catch (InterruptedException e) {

			e.printStackTrace();
		}
	}

	@Override
	/**
	 * @see abordagem.leitores_e_escritores.RWLock
	 */
	public void releaseReadLock() {

		try {

			mutex.acquire();
			--readerCount;
			
			if (readerCount == 0) {
				db.release();
			}

			mutex.release();

		} catch (InterruptedException e) {

			e.printStackTrace();
		}

	}

	@Override
	/**
	 * @see abordagem.leitores_e_escritores.RWLock
	 */
	public void releaseWriteLock() {

		db.release();
	}

}
